require 'rubygems'
require 'gruff'
require "report/Report"
require "report/Section"


class AverageDurationPerCorrectCharacterPerLayerBySubject
  NAME = "Average Duration Between 2 Correct Characters (Group by Subject)"
  
  def initialize
    @order = {
      2 => [1, 4, 2],
      3 => [1, 4, 2],
      4 => [1, 2 ,3],
      5 => [1, 4, 2],
      6 => [1, 3, 4]     
    }
  end
  
  
  def analyze(directory, experimentalData, phraseCards)
    
    #override the filter
    experimentalData.layer1filter = Hash.new([])
    experimentalData.getData
    
    #create the report
    report = Report.new(directory, NAME)

    #get the data
    data = experimentalData.group_by_uid

    data.each_pair do |uid, entries|
      data_by_layer = {}

      entries.each do |e|
        #initialize if nil
        data_by_layer[e.layer] ||= []
        data_by_layer[e.layer] << e
      end

      #create a graph for each subject
      g = create_graph(uid)

      #do some simple statistics
      stat = ""

      #average value of each layer
      avg_durations_of_layers = {}

      #Generate a section for each layer
      data_by_layer.each_pair do |layer, entries|
        entries.sort! { |x,y| x.date <=> y.date }

        avg_durations = entries.collect do |e|
          _get_avg_duration(e)
        end

        avg = avg_durations.inject{ |sum, el| sum + el }.to_f / avg_durations.length
        avg_durations_of_layers[layer] = avg
      end
      
      
      order = @order[uid]
      avg_duration_of_each_layer = order.collect do |i|
        avg_durations_of_layers[i]
      end
      
      #average value 
      avg = avg_duration_of_each_layer.inject{ |sum, el| sum + el }.to_f / avg_duration_of_each_layer.length
      
      stat = "<b>Average: </b> #{avg} <br/>"    
      g.data "Layers", avg_duration_of_each_layer
      report.new_section("Subject #{uid}", stat, g)

    end

    #generate report
    report.to_html
  end

  #  S  t  u  s  bs   d  e  n  t
  #   t1 t2 D  D   t5  t6 t7 t8
  def _get_avg_duration(e)
    #marks the time duratin the have to be deleted
    marks = []
    e.sequence.each do |seq|
      marks << 0
      if ( seq[0].eql?("\b"))
        marks[-2] = 1 unless marks[-2] == nil
        marks[-3] = 1 unless marks[-3] == nil
      end
    end

    durations = []
    marks[-1] = 1 # remove the last one which is always zero
    marks.length.times do |i|
      durations << e.sequence[i][1] unless marks[i]==1
    end

    return durations.inject{ |sum, el| sum + el }.to_f / durations.length
  end

  def create_graph (uid)
    g = Gruff::Line.new
    g.dot_radius = 2
    g.line_width = 2
    g.x_axis_label = "Layers : #{@order[uid].inspect}"
    g.y_axis_label = "Time (10 ms)"
    g.title = "Avg Duration Between Characters(Subject:#{uid})"
    g
  end
end